﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Common.Dao;
using Common.Model;
using GxTsSharp.Models;
using log4net;

namespace StockIndex.service
{
    //涨跌幅计算
    public class ZdfService
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(ZdfService));

        /// <summary>
        /// 计算个股涨跌幅
        /// </summary>
        /// <param name="stockInfo"></param>
        /// <param name="strMarketId"></param>
        /// <param name="quote"></param>
        public static void CalculateStockZdf()
        {
            foreach (var snapshoot in MemoryDataDB.StockSnapshoot)
            {
                var stockCode = snapshoot.Key;
                var quote = snapshoot.Value;
                if (Math.Abs(quote.Report.PrevClose) < 0.00000001 || Math.Abs(quote.Report.NewPrice) < 0.00000001)
                {
                    continue;
                }

                var zdf = Convert.ToDecimal((quote.Report.NewPrice - quote.Report.PrevClose) / quote.Report.PrevClose *
                                            100);
                if (stockCode.Equals("000001.SZ"))
                {
                    Log.Debug($"股票代码：{stockCode},涨跌幅:{zdf}");
                }

                MemoryDataDB.AddOrUpdateStockZdf(stockCode, zdf);
            }
        }

        public static void CalculateTopicZdf()
        {
            List<Task> list = new List<Task>();

            foreach (KeyValuePair<string, ConcurrentDictionary<string, decimal>> topicStockWeight in MemoryDataDB.DicTopicStockWeight)
            {
                var task = Task.Run(() =>
                {

                });
                list.Add(task);
            }

//            var orderList = MemoryDataDB.DicTopicZdf.OrderByDescending(x => x.Value).Select(x => x.Key).ToList();
            Task.WaitAll(list.ToArray());
        }

        private static void UpdateMultiDaysTopicZdf(ConcurrentDictionary<string, decimal> dicTopicPreview,
            ConcurrentDictionary<string, decimal> dictopicZdf, decimal zdfToday, string topicName)
        {
            dicTopicPreview.TryGetValue(topicName, out var zdfPre);
            var zdf = ((zdfPre / 100 + 1) * (zdfToday / 100 + 1) - 1) * 100;
            dictopicZdf.AddOrUpdate(topicName, zdf, (k, v) => zdf);
        }

        //计算股票n日涨跌幅
        public static void CalculateStockPreviewNDaysZdf(int n, ConcurrentDictionary<string, decimal> dicZdf)
        {
            //获取开始和结束日期
            List<DateTime> beginDateAndEndDate =
                TradeDateDao.GetLastNBeginDateAndEndDateWithoutToday(n, DateTime.Now.Date);
            if (beginDateAndEndDate == null || beginDateAndEndDate.Count != 2)
            {
                Log.Error("日期不对");
                throw new Exception("日期不对");
            }

            DateTime beginDate = beginDateAndEndDate.First();
            DateTime endDate = beginDateAndEndDate.Last();
            //计算涨跌幅
            List<ZdfModel> zdfModels = DailyKLineDao.GetZdf(beginDate, endDate);

            if (zdfModels == null || zdfModels.Count == 0)
            {
                Log.Info($"没{n}日涨跌幅数据");
                return;
            }

//            DicZdf.Clear();
            foreach (var zdfModel in zdfModels)
            {
                dicZdf.AddOrUpdate(zdfModel.StockCode, zdfModel.Zdf, (k, v) => zdfModel.Zdf);
            }
        }


        private static void FullMultiPreviewStockZdf()
        {
            Log.Info("开始同步多日股票涨跌幅pre");
            CalculateStockPreviewNDaysZdf(2, MemoryDataDB.Dic2DaysStockZdfYd);
            CalculateStockPreviewNDaysZdf(4, MemoryDataDB.Dic4DaysStockZdfYd);
            CalculateStockPreviewNDaysZdf(9, MemoryDataDB.Dic9DaysStockZdfYd);
            CalculateStockPreviewNDaysZdf(19, MemoryDataDB.Dic19DaysStockZdfYd);
            Log.Info("同步多日股票涨跌幅完成pre");
        }

        public static void FullMultiPreviewTopicZdf()
        {
            FullMultiPreviewStockZdf();
            Log.Info("同步多日主题涨跌幅pre");
            foreach (var topicStockWeight in MemoryDataDB.DicTopicStockWeight)
            {
                var topicName = topicStockWeight.Key;
                var dicStockWeight = topicStockWeight.Value;

                var sum2D = 0m;
                var sum4D = 0m;
                var sum9D = 0m;
                var sum19D = 0m;
                foreach (var stockWeight in dicStockWeight)
                {
                    var stockCode = stockWeight.Key;
                    var weight = stockWeight.Value;
                    var stockZdf2Day = MemoryDataDB.GetNPreviewStockZdf(stockCode, 2);
                    var stockZdf4Day = MemoryDataDB.GetNPreviewStockZdf(stockCode, 4);
                    var stockZdf9Day = MemoryDataDB.GetNPreviewStockZdf(stockCode, 9);
                    var stocZdf19Day = MemoryDataDB.GetNPreviewStockZdf(stockCode, 19);
                    sum2D += stockZdf2Day * weight;
                    sum4D += stockZdf4Day * weight;
                    sum9D += stockZdf9Day * weight;
                    sum19D += stocZdf19Day * weight;
                }

                MemoryDataDB.Dic2DaysTopicZdfYd.AddOrUpdate(topicName, sum2D, (k, v) => sum2D);
                MemoryDataDB.Dic4DaysTopicZdfYd.AddOrUpdate(topicName, sum4D, (k, v) => sum4D);
                MemoryDataDB.Dic9DaysTopicZdfYd.AddOrUpdate(topicName, sum9D, (k, v) => sum9D);
                MemoryDataDB.Dic19DaysTopicZdfYd.AddOrUpdate(topicName, sum19D, (k, v) => sum19D);
            }

            Log.Info("同步多日主题涨跌幅完成pre");
        }
    }
}